﻿using YooAssetsSystem.Fsm;
using UnityEngine;
using YooAsset;

namespace YooAssetsSystem.Patch
{
	/// <summary>
	/// 下载状态 5
	/// </summary>
	public class DownloadFilesNode : BasePatchNode
	{
		private float timer;
		private long bytes;

		public override void OnEnter()
		{
			timer = 0;
			bytes = 0;

			var downloaderOperation = shareData.downloader;
			if (downloaderOperation != null)
			{
				Owner.Event.ChangeStateEvent?.Invoke("正在下载资源...");
				downloaderOperation.DownloadUpdateCallback = OnDownloadProgressCallback;
				downloaderOperation.Completed += DownloaderOperationOnCompleted;
				downloaderOperation.DownloadErrorCallback += OnDownloadErrorCallback;
				downloaderOperation.BeginDownload();
			}
			else
			{
				Debug.LogError("downloaderOperation is null");
				Owner.Event.UpdateFailedEvent?.Invoke($"{GetType().Name}失败, 停止更新");
			}
		}

		public override void OnUpdate()
		{
			if (shareData.pauseDownload)
			{
				shareData.downloader?.PauseDownload();
			}
			else
			{
				shareData.downloader?.ResumeDownload();
			}
		}

		public override void OnExit()
		{
			shareData.downloader?.CancelDownload();
		}

		void OnDownloadProgressCallback(DownloadUpdateData data)
		{
			if (Time.realtimeSinceStartup - timer >= 1f)
			{
				Owner.Event.DownloadSpeedEvent?.Invoke(Mathf.Clamp((data.CurrentDownloadBytes - bytes) / 1024f, 0,
					float.MaxValue));
				bytes = data.CurrentDownloadBytes;
				timer = Time.realtimeSinceStartup;
			}

			Owner.Event.DownloadProgressEvent?.Invoke(data.TotalDownloadCount, data.CurrentDownloadCount,
				data.TotalDownloadBytes, data.CurrentDownloadBytes);
		}

		void DownloaderOperationOnCompleted(AsyncOperationBase operationBase)
		{
			if (operationBase.Status == EOperationStatus.Succeed)
			{
				Owner.Event.ChangeStateEvent?.Invoke("资源下载完成");
				machine.ChangeState<PatchDoneNode>();
			}
			else
			{
				Debug.LogError(operationBase.Error);
				Owner.Event.UpdateFailedEvent?.Invoke($"{GetType().Name}失败, 停止更新");
			}
		}

		private void OnDownloadErrorCallback(DownloadErrorData data)
		{
			Debug.LogError($"包: {data.PackageName} 中的 {data.FileName} 下载失败, error: {data.ErrorInfo}");
			Owner.Event.UpdateFailedEvent?.Invoke($"{GetType().Name}失败, 停止更新");
		}
	}
}
